package com.mspbots.ticketai.graderule;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.ticketai.GradeRuleInterceptorAdapter;
import com.mspbots.ticketai.model.Ticket;
import com.mspbots.ticketai.model.TicketRule;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Log4j2
@Service(value = "MEMBER_SKILLS_POINT_RULE")
public class MemberSkillsRuleInterceptor extends GradeRuleInterceptorAdapter {

    private List<MemberSkillsParam> params;

    @Override
    public void prepare(TicketRule rule) {
        params = this.objectMapper.convertValue(rule.getParams(), new TypeReference<>() {
        });
    }

    @Override
    public void process(Ticket ticket) {
        AtomicInteger order = new AtomicInteger();
        ObjectNode orderDetailNode = ticket.getOrderDetail() == null ? this.objectMapper.createObjectNode() : ticket.getOrderDetail().deepCopy();
        ObjectNode itemsNode = this.objectMapper.createObjectNode();
        String type = ticket.getExtend().get("type") == null ? "" : ticket.getExtend().get("type").get("name").asText();
        String subType = ticket.getExtend().get("subType") == null ? "" : ticket.getExtend().get("subType").get("name").asText();
        String ticketItem = ticket.getExtend().get("item") == null ? "" : ticket.getExtend().get("item").get("name").asText();
        if (!CollectionUtils.isEmpty(ticket.getMemberSkillNames()) && !StringUtils.isEmpty(ticket.getIdentifier()) && type != null) {
            params.stream().filter(p -> p.isSelected() && !CollectionUtils.isEmpty(p.getMemberSkills()) && !StringUtils.isEmpty(p.getType()))
                    .forEach(item -> {
                                boolean flag = item.getMemberSkills().stream().anyMatch(skill -> ticket.getMemberSkillNames().contains(skill));
                                if (flag && type.equals(item.getType())) {
                                    if (StringUtils.isEmpty(subType) && CollectionUtils.isEmpty(item.getSubtypes())) {
                                        order.addAndGet(item.getPoints());
                                    } else if (!StringUtils.isEmpty(subType) && !CollectionUtils.isEmpty(item.getSubtypes())
                                            && item.getSubtypes().contains(subType)) {
                                        if (StringUtils.isEmpty(ticketItem) && CollectionUtils.isEmpty(item.getItems())) {
                                            order.addAndGet(item.getPoints());
                                        } else if (!StringUtils.isEmpty(ticketItem) && !CollectionUtils.isEmpty(item.getItems())
                                                && item.getItems().contains(ticketItem)) {
                                            order.addAndGet(item.getPoints());
                                        }
                                    }
                                }
                            }
                    );
        }
        itemsNode.put("memberSkills", CollectionUtils.isEmpty(ticket.getMemberSkillNames()) ? null : String.join(", ", ticket.getMemberSkillNames()));
        itemsNode.put("type", type);
        itemsNode.put("subType", subType);
        itemsNode.put("item", ticketItem);
        itemsNode.put("point", order.get());
        orderDetailNode.set("memberSkills", itemsNode);
        ticket.setOrderDetail(orderDetailNode);
        ticket.setOrder(ticket.getOrder() + order.get());
    }

    @Data
    private static class MemberSkillsParam {
        private List<String> memberSkills;
        private String type;
        private List<String> subtypes;
        private List<String> items;
        private Integer points;
        private boolean selected;
    }
}
